<?php


namespace IDock\Insurance\DBIC;

use IDock\Http\Response;
use IDock\IDock\IDockInterface;
use IDock\Insurance\DBIC\Request\EPolicyDownloadRequest;
use IDock\Insurance\DBIC\Request\LoginTokenRequest;
use IDock\Insurance\DBIC\Request\NonCarProductListRequest;
use IDock\Insurance\DBIC\Request\PolicyPaymentRequest;
use IDock\Insurance\DBIC\Request\PremiumInquiryRequest;
use IDock\Insurance\DBIC\Request\PremiumInquirySaveRequest;
use IDock\Insurance\DBIC\Request\PremiumInquiryUpdateRequest;
use IDock\Insurance\DBIC\Request\ProductClauseRequest;
use IDock\Insurance\DBIC\Request\ProposalRecallRequest;
use IDock\Insurance\DBIC\Request\ProposalStatusRequest;
use IDock\Insurance\DBIC\Request\ProposalStatusUWRequest;
use IDock\Insurance\DBIC\Request\RSAPublicKeyRequest;
use IDock\Insurance\DBIC\Request\SpecialClausesRequest;
use IDock\Insurance\DBIC\Request\UnderwritingRequest;
use IDock\Insurance\DBIC\Request\UploadFileRequest;
use IDock\Insurance\DBIC\Request\ValidateCarRequest;
use IDock\Insurance\DBIC\Request\VehicleActualValueRequest;
use IDock\Insurance\DBIC\Request\VehicleModelRequest;
use IDock\Insurance\DBIC\Response\EPolicyDownloadResponse;
use IDock\Insurance\DBIC\Response\LoginTokenResponse;
use IDock\Insurance\DBIC\Response\NonCarProductListResponse;
use IDock\Insurance\DBIC\Response\PolicyPaymentResponse;
use IDock\Insurance\DBIC\Response\PremiumInquiryResponse;
use IDock\Insurance\DBIC\Response\PremiumInquirySaveResponse;
use IDock\Insurance\DBIC\Response\ProductClauseResponse;
use IDock\Insurance\DBIC\Response\ProposalRecallResponse;
use IDock\Insurance\DBIC\Response\ProposalStatusResponse;
use IDock\Insurance\DBIC\Response\ProposalStatusUWResponse;
use IDock\Insurance\DBIC\Response\RSAPublicKeyResponse;
use IDock\Insurance\DBIC\Response\SpecialClausesResponse;
use IDock\Insurance\DBIC\Response\UnderwritingResponse;
use IDock\Insurance\DBIC\Response\UploadFileResponse;
use IDock\Insurance\DBIC\Response\ValidateCarResponse;
use IDock\Insurance\DBIC\Response\VehicleActualValueResponse;
use IDock\Insurance\DBIC\Response\VehicleModelResponse;
use IDock\Printer\NonCar\NonCarInquiryPrinter;
use IDock\Printer\NonCar\NonCarInquirySinglePrinter;
use IDock\Printer\ProposalStatusPrinter;
use IDock\Visitor\EPolicyDownloadVisitor;
use IDock\Visitor\NonCar\NonCarInquiryVisitor;
use IDock\Visitor\NonCar\NonCarProductListVisitor;
use IDock\Visitor\NonCar\NonCarProductVisitor;
use IDock\Visitor\PolicyInfoVisitor;
use IDock\Visitor\PolicyPaymentVisitor;
use IDock\Visitor\Premium\PremiumInquiryVisitor;
use IDock\Visitor\ProposalRecallVisitor;
use IDock\Visitor\ProposalStatusVisitor;
use IDock\Visitor\RenewalInquiryVisitor;
use IDock\Visitor\UnderwritingRecallVisitor;
use IDock\Visitor\UploadFileVisitor;
use IDock\Visitor\ValidateCarVisitor;
use IDock\Visitor\VehicleActualValueVisitor;
use IDock\Visitor\VehicleModelVisitor;

class DBICConstruct extends Builder implements IDockInterface
{
    public $config = [];

    public function __construct($config)
    {
        $this->config = $config;

        $this->usercode = $config['usercode'] ?? '';
        $this->password = $config['password'] ?? '';
        $this->key = $config['key'] ?? '';
        $this->module16 = $config['module16'] ?? '';
        $this->exponent16 = $config['exponent16'] ?? '';
        $this->passwordRsANoPadding = $config['passwordRsANoPadding'] ?? '';
        $this->payKey = $config['payKey'] ?? '';
        $this->machId = $config['MCHID'] ?? '';
        $this->goodDirection = $config['GOODDIRECTION'] ?? '';
        $this->backCallUrl = $config['BACKCALLURL'] ?? '';
    }

    /**
     * token
     * @param string $token
     * @return void
     * @version 4.0
     */
    public function setToken(string $token)
    {
        $this->token = $token;
    }

    /**
     * RSA 证书获取
     * @return RSAPublicKeyResponse
     * @version 4.0
     */
    public function rsaPublicKey(): RSAPublicKeyResponse
    {
        $request = new RSAPublicKeyRequest();
        $request->setUserCode($this->usercode);

        /*** @var $response RSAPublicKeyResponse */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 获取/刷新 token
     * @return LoginTokenResponse
     * @version 4.0
     */
    public function loginToken(): LoginTokenResponse
    {
        $request = new LoginTokenRequest();
        $request->setUserCode($this->usercode);
        $request->setPassWord($this->password);
        $request->setModule16($this->module16);
        $request->setExponent16($this->exponent16);
        $request->setPasswordRsANoPadding($this->passwordRsANoPadding);

        /*** @var $response LoginTokenResponse */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 可投险别初始化接口
     * @return ProductClauseResponse
     */
    public function productClause(): ProductClauseResponse
    {
        $request = new ProductClauseRequest();

        /*** @var $response ProductClauseResponse */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 特约初始化接口
     * @param PremiumInquiryVisitor $visitor
     * @param $VCIResponse
     * @param $TCIResponse
     */
    public function specialClauses(PremiumInquiryVisitor $visitor, &$VCIResponse, &$TCIResponse)
    {
        $request = new SpecialClausesRequest();

        $request->setVisitor($visitor);

        if ($visitor->getBiStartData()) {
            $request->setBi();
            /*** @var $response SpecialClausesResponse */
            $VCIResponse = $this->execute($request);
        }

        if ($visitor->getCiStartData()) {
            $request->setCi();
            /*** @var $response SpecialClausesResponse */
            $TCIResponse = $this->execute($request);
        }
    }

    /**
     * 询价单保存
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return PremiumInquirySaveResponse
     */
    public function premiumInquirySave(PremiumInquiryVisitor $premiumInquiryVisitor): PremiumInquirySaveResponse
    {
        $request = new PremiumInquirySaveRequest();
        $request->setVisitor($premiumInquiryVisitor);

        /*** @var PremiumInquirySaveResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 询价单更新
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return PremiumInquirySaveResponse
     */
    public function premiumInquiryUpdate(PremiumInquiryVisitor $premiumInquiryVisitor): PremiumInquirySaveResponse
    {
        $request = new PremiumInquiryUpdateRequest();
        $request->setVisitor($premiumInquiryVisitor);

        /*** @var PremiumInquirySaveResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 续保查询
     * @param RenewalInquiryVisitor $renewalInquiryVisitor
     */
    public function renewalInquiry(RenewalInquiryVisitor $renewalInquiryVisitor)
    {
    }

    /**
     * 车型查询
     * @param VehicleModelVisitor $vehicleModelVisitor
     * @return VehicleModelResponse
     */
    public function vehicleModel(VehicleModelVisitor $vehicleModelVisitor): VehicleModelResponse
    {
        $request = new VehicleModelRequest();
        $request->setVisitor($vehicleModelVisitor);

        /*** @var VehicleModelResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 车辆实际价格
     * @param VehicleActualValueVisitor $vehicleActualValueVisitor
     * @return VehicleActualValueResponse
     */
    public function vehicleActualValue(VehicleActualValueVisitor $vehicleActualValueVisitor): VehicleActualValueResponse
    {
        $request = new VehicleActualValueRequest();
        $request->setVisitor($vehicleActualValueVisitor);

        /*** @var VehicleActualValueResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 询价前置
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return void
     */
    public function preInquiry(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
    }

    public function validateCar(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
    }

    /**
     * 询价
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return PremiumInquiryResponse|SpecialClausesResponse
     */
    public function premiumInquiry(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
        $request = new PremiumInquiryRequest;
        $request->setVisitor($premiumInquiryVisitor);

        /*** @var PremiumInquiryResponse $response */
        $response = $this->execute($request);

        if (!$response->isSuccess()) {
            return $response;
        }

        if (!$response->printer->success) {
            return $response;
        }

        $response->buildCoverage($premiumInquiryVisitor->getVehicleVisitor()->isNewEnergy, $premiumInquiryVisitor->getCoverageVisitorList());

        $response->printer->biPremiumPrinter->biStartData = $premiumInquiryVisitor->biStartData;
        $response->printer->biPremiumPrinter->biEndData = $premiumInquiryVisitor->biEndData;
        $response->printer->ciPremiumPrinter->ciStartData = $premiumInquiryVisitor->ciStartData;
        $response->printer->ciPremiumPrinter->ciEndData = $premiumInquiryVisitor->ciEndData;
        //非车参数
        if(!empty($response->printer->nonCarInquiryPrinter->getNonCarInquirySingle())){
            /**@var NonCarProductVisitor $noCarPlan */
            $noCarPlan = $premiumInquiryVisitor->getNonCarInquiryVisitor()->getNonCarList()[0] ?? [];
            /**@var NonCarInquirySinglePrinter $single **/
            $single = $response->printer->nonCarInquiryPrinter->getNonCarInquirySingle()[0] ?? [];
            $single->insuredNum = $noCarPlan->insuredNum ?? '1';
            $single->planCode = $noCarPlan->planCode ?? '';
            $single->productCode = $noCarPlan->productCode ?? '';
            $single->premium = round($response->printer->nonCarInquiryPrinter->totalPremium / $noCarPlan->insuredNum ?? 1,2);
        }
        $VCIResponse = $TCIResponse = '';

        //获取特约
        /**
         * @var $VCIResponse SpecialClausesResponse
         * @var $TCIResponse SpecialClausesResponse
         */
        $this->specialClauses($premiumInquiryVisitor, $VCIResponse, $TCIResponse);
        if ($VCIResponse and !$VCIResponse->isSuccess()) {
            return $VCIResponse;
        }
        if ($TCIResponse and !$TCIResponse->isSuccess()) {
            return $TCIResponse;
        }

        $response->setSpecialClauses($VCIResponse, $TCIResponse);

        return $response;
    }

    /**
     * 核保
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return PremiumInquirySaveResponse|UnderwritingResponse
     */
    public function underwriting(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
        //询价单保存
        if (!$premiumInquiryVisitor->getUnderwritingVisitor()->inquiryNo) {
            $response = $this->premiumInquirySave($premiumInquiryVisitor);
            if (!$response->isSuccess()) {
                return $response;
            }
            $premiumInquiryVisitor->getUnderwritingVisitor()->inquiryNo = $response->getInquiryNo();
        } else {
            //询价单更新
            $response = $this->premiumInquiryUpdate($premiumInquiryVisitor);
            if (!$response->isSuccess()) {
                return $response;
            }
        }

        //核保
        $request = new UnderwritingRequest();
        $request->setVisitor($premiumInquiryVisitor);

        /*** @var UnderwritingResponse $response */
        $response = $this->execute($request);
        $response->printer->inquiryNo = $premiumInquiryVisitor->getUnderwritingVisitor()->inquiryNo;


        if (!$response->isSuccess()) {
            return $response;
        }

        //文件上传
        $request = new UploadFileRequest();
        if ($premiumInquiryVisitor->getFileList()) {
            $request->setVisitor($premiumInquiryVisitor);
            $request->setInquiryNo($response->printer->inquiryNo);

            /*** @var UploadFileResponse $response */
            $fileResponseFile = $this->execute($request);
        }

        return $response;
    }

    /**
     * 投保单状态查询
     * @param ProposalStatusVisitor $proposalStatusVisitor
     * @return ProposalStatusResponse
     */
    public function proposalStatus(ProposalStatusVisitor $proposalStatusVisitor): ProposalStatusResponse
    {
        $request = new ProposalStatusRequest();
        $request->setVisitor($proposalStatusVisitor);

        /*** @var ProposalStatusResponse $response */
        $response = $this->execute($request);

        if (!$response->isSuccess()) {
            return  $response;
        }
        if ($proposalStatusVisitor->ciInquiryNo) {
            $response->setCiInquiryNo($proposalStatusVisitor->ciInquiryNo);
        }

        if ($proposalStatusVisitor->biInquiryNo) {
            $response->setBiInquiryNo($proposalStatusVisitor->biInquiryNo);
        }

        //核保成功
        if  ($response->printer->statusCode == 'U1') {
            return $response;
        }

        //核保失败
        if ($response->printer->statusCode != 'U2') {
            return $response;
        } else {
            $messageTip = '';
            foreach (array_filter([$proposalStatusVisitor->biInquiryNo,$proposalStatusVisitor->ciInquiryNo]) as $inquiryNo) {
                //获取人工核保意见
                $statsRequest = new ProposalStatusUWRequest();
                $statsRequest->inquiryNo = $inquiryNo;
                $statsResponse = $this->execute($statsRequest);
                if (!$statsResponse->isSuccess()) {
                    return $response;
                }
                /*** @var $statsResponse ProposalStatusUWResponse */
                if ($statsResponse->getUnderwrite()) {
                    $messageTip .= $statsResponse->getUnderwrite();
                }

            }
            $response->printer->messageTip = $messageTip;
        }

        return $response;
    }

    /**
     * 投保单撤单（删除）接口
     * @param ProposalRecallVisitor $revokeVisitor
     * @return ProposalRecallResponse
     */
    public function proposalRecall(ProposalRecallVisitor $revokeVisitor): ProposalRecallResponse
    {
        $request = new ProposalRecallRequest();
        $request->setVisitor($revokeVisitor);

        /*** @var ProposalRecallResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 支付
     * @param PolicyPaymentVisitor $paymentVisitor
     * @return PolicyPaymentResponse|ProposalStatusResponse
     */
    public function policyPayment(PolicyPaymentVisitor $paymentVisitor)
    {
        $request = new PolicyPaymentRequest();
        $request->setPayKey($this->payKey);
        $request->setMachId($this->machId);
        $request->setGoodDirection($this->goodDirection);
        $request->setBackCallUrl($this->backCallUrl);

        if (!$paymentVisitor->biPolicyNo and !$paymentVisitor->ciPolicyNo) {
            //更新投保单号 获取最新保单号
            $proposalStatusVisitor = new ProposalStatusVisitor();
            $proposalStatusVisitor->inquiryNo = $paymentVisitor->inquiryNo;

            $responseStatus = $this->proposalStatus($proposalStatusVisitor);
            $responseStatus->setBiInquiryNo($paymentVisitor->biInquiryNo);
            $responseStatus->setCiInquiryNo($paymentVisitor->ciInquiryNo);
            if (!$responseStatus->isSuccess()) {
                return $responseStatus;
            }

            /*** @var $printer ProposalStatusPrinter */
            $printer = $responseStatus->getPrinter();

            $paymentVisitor->biPolicyNo = $printer->biPolicyNo;
            $paymentVisitor->ciPolicyNo = $printer->ciPolicyNo;
        }

        $request->setVisitor($paymentVisitor);

        /*** @var PolicyPaymentResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 文件上传
     * @param UploadFileVisitor $uploadFileVisitor
     * @return Response
     */
    public function uploadFile(UploadFileVisitor $uploadFileVisitor)
    {
        $response =   new UploadFileResponse(200,[]);
        $response->printerInit();
        return $response;
        //return new Response(200);
    }


    /**
     * 核保撤回
     * @param UnderwritingRecallVisitor $recallVisitor
     * @return Response
     */
    public function underwritingRecall(UnderwritingRecallVisitor $recallVisitor): Response
    {
        return new Response(200);
    }


    /**
     * 电子保单下载
     * @param EPolicyDownloadVisitor $EPolicyVisitor
     * @return EPolicyDownloadResponse
     */
    public function EPolicyDownload(EPolicyDownloadVisitor $EPolicyVisitor): EPolicyDownloadResponse
    {
        $request = new EPolicyDownloadRequest();
        $request->setVisitor($EPolicyVisitor);

        /*** @var EPolicyDownloadResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 驾意险列表
     * @param NonCarProductListVisitor $nonCarProductListVisitor
     * @return Response
     */
    public function nonCarProductList(NonCarProductListVisitor $nonCarProductListVisitor): Response
    {

        $response = new NonCarProductListResponse();
        $response->setCode(200);
        $response->printerInit();
        return $response;
    }

    public function nonCarInquiry(NonCarInquiryVisitor $nonCarInquiryVisitor): Response
    {
        return new Response(200);
    }

    public function nonCarUnderwriting(NonCarInquiryVisitor $inquiryPrinter): Response
    {
        return new Response(200);
    }

    public function policyInfo(PolicyInfoVisitor $policyInfoVisitor): Response
    {
        $visitor = new ProposalStatusVisitor();
        $visitor->argc = $policyInfoVisitor->argc;
        $visitor->inquiryNo = $policyInfoVisitor->policyNo;
        return $this->proposalStatus($visitor);
    }

    /**
     * 验车码
     * @param ValidateCarVisitor $validateCarVisitor
     * @return ValidateCarResponse
     */
    public function validateCarCode(ValidateCarVisitor $validateCarVisitor): ValidateCarResponse
    {
        $request = new ValidateCarRequest();

        /*** @var $response ValidateCarResponse */
        $response = $this->execute($request);

        return $response;
    }

    /**
     * 新车备案
     * @return void
     */
    public function newVehicleRegistration(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
    }
}
